/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

import path from 'path';

import { TaskDetails, TaskInputValue , FileSet } from '@ohos/hvigor';
import { ProjectConfig } from '@ohos/hvigor-arkts-compose';
import * as fse from 'fs-extra';

import { ApiVersion } from '../../const/sdk-const.js';
import { CodeType } from '../../enum/code-type-enum.js';
import { getJson5Obj } from '../../utils/json-util.js';
import { OhosLogger } from '../../utils/log/ohos-logger.js';
import { limitMinApiVersion } from '../../utils/task-util.js';
import { ArkCompile } from '../ark-compile.js';
import { TaskNames } from '../common/task-names.js';
import { CompileResource } from '../compile-resource.js';
import { GenerateLoaderJson } from '../generate-loader-json.js';
import { TargetTaskService } from '../service/target-task-service.js';
import { packageJsonValidMainField } from './core-process-package-json.js';
import { ObfuscateType } from './har-compile-node.js';

import CommonTask = TaskNames.CommonTask;
import { getOhosUiTransformOptimization } from "../module-info/ohos-uitransform-optimization.js";


export class HarArkCompile extends ArkCompile {
  protected _log: OhosLogger = OhosLogger.getLogger(HarArkCompile.name);

  constructor(taskService: TargetTaskService, codeType: CodeType, taskDetails: TaskDetails) {
    super(taskService, codeType, taskDetails);

    // 字节码har，保持原有路径
    if (!this.targetService.isByteCodeHar()) {
      // output assets dir
      this.aceModuleBuild = path.resolve(this.pathInfo.getInterMediatesLoaderOutPath());
    }
  }

  declareInputs(): Map<string, TaskInputValue> {
    return super
      .declareInputs()
      .set('isByteCodeHar', this.targetService.isByteCodeHar())
      .set('isBundledDependencies', this.targetService.isBundledDependencies());
  }

  declareInputFiles(): FileSet {
    const fileSet = super.declareInputFiles();

    if (packageJsonValidMainField) {
      // 此处获取的packageJsonValidMainField一定是存在和合法的
      const harExportMainEntryFilePath = path.resolve(this.moduleModel.getProjectDir(), packageJsonValidMainField!);
      if (fse.existsSync(harExportMainEntryFilePath)) {
        fileSet.addEntry(harExportMainEntryFilePath);
      }
    }

    // 获取当前模块的buildProfile.ets文件 如果存在添加增量判断
    const harBuildProfilePath = this.pathInfo.getHarGenerateBuildProfilePath();
    if (fse.existsSync(harBuildProfilePath)) {
      fileSet.addEntry(harBuildProfilePath);
    }

    return fileSet;
  }

  protected async doTaskAction(): Promise<void> {
    await super.doTaskAction();
  }

  protected async initDefaultArkCompileConfig() {
    const isByteCodeHar = this.targetService.isByteCodeHar();
    if (!this.buildOption?.debuggable
        && !isByteCodeHar
        && this.targetService.getBuildOption()?.arkOptions?.branchElimination) {
      this._log.warn(`Because you have set 'byteCodeHar' to false in ${this.moduleName}'s build-profile.json5, branchElimination will have no effect. ` +
        'Only in release mode and set \'byteCodeHar\' to true, that the branchElimination will have effect.');
    }
    const compileConfig = {
      ...(await super.initDefaultArkCompileConfig()),
      byteCodeHar: isByteCodeHar,
      obfuscate: this.targetService.isOpenSource() ? undefined : ObfuscateType.UGLIFY,

      // 跳过arkts编译的buildEnd阶段，不生成abc文件，字节码har除外
      skipBuildEnd: !isByteCodeHar && this.targetService.isOpenSource() && !getOhosUiTransformOptimization(this.targetService),
      compileBlockPkg: this.getDependencyKeys(),
    } as ProjectConfig;

    return compileConfig;
  }

  initTaskDepends(): void {
    if (limitMinApiVersion(this.targetData, ApiVersion.API_VERSION_9)) {
      this.declareDependsList(GenerateLoaderJson.name, CompileResource.name, CommonTask.CREATE_HAR_BUILD_PROFILE.name);
    } else {
      this.declareDependsList(GenerateLoaderJson.name, CompileResource.name);
    }
  }

  private getDependencyKeysByPkgPath(pkgPath: string): Record<string, string> {
    const pkgJson = getJson5Obj(pkgPath);
    if (!pkgJson) {
      return {};
    }
    return {
      ...(pkgJson.dependencies ?? {}),
      ...(pkgJson.devDependencies ?? {}),
      ...(pkgJson.dynamicDependencies ?? {}),
    };
  }

  private getDependencyKeys() {
    if (this.targetService.isBundledDependencies()) {
      const dependencies = this.isByteCodeHarOptimize ?
        this.service.getAffectsCompilationDependencies().filter(dependency => dependency.isHspDependency() || dependency.isOtherDependency() || dependency.isByteCodeHarDependency()) :
        this.service.getHspOrByteCodeHarDependencies().concat(this.service.getOtherDependencies());
      return  dependencies.map((dependency) => dependency.getDependencyName());
    }
    const selfDeps = this.getDependencyKeysByPkgPath(this.moduleModel.getOhPackageJson5Path());
    // 字节码HAR场景下，工程级&自身依赖都需要被阻断
    const allDeps = this.targetService.isByteCodeHar() ?
      { ...this.getDependencyKeysByPkgPath(this.projectModel.getOhPackageJson5Path()), ...selfDeps } :
      selfDeps;

    return Object.keys(allDeps);
  }
}
